﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace QuickTweet.Common
{
    public abstract class ObservableObject : INotifyPropertyChanged
    {
        protected virtual bool UpdateProperty<T>(T value, ref T variable)
        {
            bool changed = false;
            if (!EqualityComparer<T>.Default.Equals(value, variable))
            {
                variable = value;
                changed = true;
            }

            return changed;
        }

        protected virtual void OnPropertyChanged()
        {
            if (PropertyChanged != null)
            {
                //Recupera il nome della proprietà chiamante.            
                StackTrace stackTrace = new StackTrace();
                var propertyName = stackTrace.GetFrame(1).GetMethod().Name;
                int pos = propertyName.IndexOf("set_");
                if (pos > -1)
                    propertyName = propertyName.Substring(4);
                else
                    throw new ArgumentException("OnPropertyChanged called from an invalid property");

                OnPropertyChanged(propertyName);
            }
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                //Lancia l'evento.
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private static string GetPropertySymbol<TResult>(Expression<Func<TResult>> expr)
        {
            return ((MemberExpression)expr.Body).Member.Name;
        }

        protected virtual void OnPropertyChanged<PropertyType>(Expression<Func<PropertyType>> propertyExpr)
        {
            string propertyName = GetPropertySymbol(propertyExpr);
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        protected virtual void OnPropertyChanged(object sender, string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
